﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using hvppleDotNet;

namespace HangzhouChipProject
{
    
    class PictureProcess
    {
        /// <summary>
        /// 显示图像
        /// </summary>
        /// <param name="himage"></param>
        /// <param name="hSmartWindow"></param>
        public static void pShowPictureToHwindows(HObject himage,HTuple hSmartWindow)
        {
            HOperatorSet.GetImageSize(himage, out HTuple Iwidth, out HTuple Iheight);
            HOperatorSet.SetPart(hSmartWindow.H, 0,0, Iheight - 1, Iwidth - 1);
            HOperatorSet.ClearWindow(hSmartWindow);
            HOperatorSet.DispObj(himage, hSmartWindow);           
        }
        public static HObject bitmapToHobject(Bitmap bitmap)
        {
            Rectangle imgRect = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
            BitmapData bitData = bitmap.LockBits(imgRect, ImageLockMode.ReadOnly, bitmap.PixelFormat);
            HObject image;
            switch (bitmap.PixelFormat)
            {
              
                case PixelFormat.Format8bppIndexed:
                    HOperatorSet.GenImage1(out  image, "byte", bitmap.Width, bitmap.Height, bitData.Scan0);
                    break;
                case PixelFormat.Format24bppRgb:
                    HOperatorSet.GenImageInterleaved(out  image, bitData.Scan0, "bgr", bitmap.Width, bitmap.Height, 0, "byte", bitmap.Width, bitmap.Height, 0, 0, -1, 0);
                    break;
            
                default:
                    HOperatorSet.GenImage1(out  image, "byte", bitmap.Width, bitmap.Height, bitData.Scan0);
                    break;
            }
            bitmap.UnlockBits(bitData);
            return image;
        }
        public static HObject bitmapToHobject32(Bitmap bitmap)
        {
        
            Rectangle imgRect = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
            BitmapData bitData = bitmap.LockBits(imgRect, ImageLockMode.ReadOnly, bitmap.PixelFormat);
            HObject image;
            switch (bitmap.PixelFormat)
            {

                case PixelFormat.Format8bppIndexed:
                    HOperatorSet.GenImage1(out image, "byte", bitmap.Width, bitmap.Height, bitData.Scan0);
                    break;
                case PixelFormat.Format24bppRgb:
                    HOperatorSet.GenImageInterleaved(out image, bitData.Scan0, "bgr", bitmap.Width, bitmap.Height, 0, "byte", bitmap.Width, bitmap.Height, 0, 0, -1, 0);
                    break;
                default:
                    HOperatorSet.GenImage1(out image, "byte", bitmap.Width, bitmap.Height, bitData.Scan0);
                    break;
            }
            bitmap.UnlockBits(bitData);
            return image;
        }
        /// <summary>
        /// 保存图像
        /// </summary>
        /// <param name="himage"></param>
        /// <param name="hwindowsdump">窗口绘制的不可见窗口</param>
        /// <returns></returns>
        public static bool pSavePictrue(HObject himage,HWindow hwindowsdump)
        {

            try
            {
                if (himage.IsInitialized()==false)
                {
                    return false;
                }
                HOperatorSet.GetImageSize(himage,out HTuple W, out HTuple H);
                hwindowsdump.SetWindowExtents(0,0,W,H);
                HOperatorSet.SetPart(hwindowsdump,0,0,W-1,H-1);
                HOperatorSet.DispObj(himage,hwindowsdump);
                HOperatorSet.WriteImage(himage,"bmp", 0, AppDomain.CurrentDomain.BaseDirectory + "Image\\Saveimage\\" + DateTime.Now.ToString("yyyy.MM.dd.HH.mm.ss"));
                return true;
            }
            catch (Exception )
            {

                return false;
            }

        }
        public static HTuple CreataModel(HTuple hwindowshandel, HObject imagemodel,Dictionary<string, string> modelData)
        {
            int contrastlow = Convert.ToInt32(modelData["ContrastLow"]);
            int contrasthigh = Convert.ToInt32(modelData["ContrastHigh"]);
            int smallest = Convert.ToInt32(modelData["Smallest"]);
            int numLevels = Convert.ToInt32(modelData["NumLevels"]);
            int angleStart = Convert.ToInt32(modelData["AngleStart"]);
            int angleExtent = Convert.ToInt32(modelData["AngleExtent"]);
            double angleStep = Convert.ToDouble(modelData["AngleStep"]);
            int minContrast = Convert.ToInt32(modelData["MinContrast"]);
            string metric = modelData["Metric"];
            if (imagemodel == null)
                return null;
            HOperatorSet.CreateShapeModel(imagemodel, numLevels, new HTuple(angleStart).TupleRad(), new HTuple(angleExtent).TupleRad(), "auto", (new HTuple("point_reduction_high")).TupleConcat(
           "no_pregeneration"), metric, ((new HTuple(contrastlow)).TupleConcat(contrasthigh)).TupleConcat(
           smallest), minContrast, out HTuple ModelID);
            HOperatorSet.GetShapeModelContours(out HObject modelContours, ModelID,1);
            HOperatorSet.AreaCenter(imagemodel, out HTuple modelarea,out HTuple modelrow,out HTuple modelcolumn);
            HOperatorSet.VectorAngleToRigid(0,0,0,modelrow,modelcolumn,0,out HTuple modelhomMat2D);
            HOperatorSet.AffineTransContourXld(modelContours,out HObject modelcontoursAffine, modelhomMat2D);
            HOperatorSet.SetColor(hwindowshandel, new HTuple("red"));
            HOperatorSet.DispObj(modelcontoursAffine, hwindowshandel);
            return ModelID;
        }
        public static HObject FindModel(HObject himage,HTuple modelID,Dictionary<string ,string > findmodeldata,out HObject ContoursCrossEmtyobj, out HTuple row, out HTuple coumn, out HTuple angle, out HTuple score)
        {
            HOperatorSet.GenEmptyObj(out HObject ContoursEmtyobj);
            HOperatorSet.GenEmptyObj(out  ContoursCrossEmtyobj);
            HTuple hHomMat2D = new HTuple();
            int angleStart = Convert.ToInt32(findmodeldata["AngleStart"]);
            int angleExtent = Convert.ToInt32(findmodeldata["AngleExtent"]);
            double minScore = Convert.ToDouble(findmodeldata["MinScore"]);
            int numMatches = Convert.ToInt32(findmodeldata["NumMatches"]);
            double maxOverlap = Convert.ToDouble(findmodeldata["MaxOverlap"]);
            int numLevels = Convert.ToInt32(findmodeldata["NumLevels"]);
            double greediness = Convert.ToDouble(findmodeldata["Greediness"]);
            string subPixel = findmodeldata["SubPixel"];
            HOperatorSet.GetShapeModelContours(out HObject modelContours, modelID, 1);
            HOperatorSet.FindShapeModel(himage, modelID, new HTuple(angleStart).TupleRad(), new HTuple(angleExtent).TupleRad(), minScore,numMatches,
             maxOverlap, subPixel,numLevels, greediness,out  row,out  coumn,out  angle,out  score) ;
            for (int i = 0; i < score.Length; i++)
            {
                hHomMat2D.Dispose();
                HOperatorSet.HomMat2dIdentity(out  hHomMat2D);
                HOperatorSet.HomMat2dRotate(hHomMat2D, angle[i], 0, 0, out hHomMat2D);
                HOperatorSet.HomMat2dTranslate(hHomMat2D, row[i], coumn[i],out hHomMat2D);
                HOperatorSet.AffineTransContourXld(modelContours,out HObject modelContoursTrans, hHomMat2D);
                HOperatorSet.GenRegionContourXld(modelContoursTrans,out HObject ContoursTransRegion, "margin");
                HOperatorSet.Union1(ContoursTransRegion,out HObject regionUnnon);
                HOperatorSet.SmallestRectangle2(regionUnnon, out HTuple RowUnnon, out HTuple ColumnUnnon, out HTuple angleUnnon, out HTuple length1Unnon, out HTuple length2Unnon) ;
                HOperatorSet.GenRectangle2(out HObject rectangle2,  RowUnnon,  ColumnUnnon,angleUnnon, length1Unnon,  length2Unnon);
                HOperatorSet.GenCrossContourXld(out HObject CrossEmtyobj, row[i], coumn[i], 100, angle[i]);
                HOperatorSet.ConcatObj(ContoursEmtyobj, rectangle2,out ContoursEmtyobj);
                HOperatorSet.ConcatObj(ContoursCrossEmtyobj, CrossEmtyobj, out ContoursCrossEmtyobj);
            }
            return ContoursEmtyobj;
        }
        public static bool SaveModel(HTuple hmodel,string modelpath)
        {
            if (hmodel == null)
                return false;
            HOperatorSet.WriteShapeModel(hmodel, modelpath);
            return true;
        }
    }
}
